home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '93 / Hacks '93 / Johan / maze.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-18  |  6.1 KB  |  244 lines  |  [TEXT/KAHL]

  1. #include "hm.h"
  2.  
  3.  
  4. unsigned char walls[] = {
  5.     0, 1, 3, 0,        // 0
  6.     2, 0, 1, 1,        // 1
  7.     1, 2, 2, 3,        // 2
  8.     3, 3, 0, 2,        // 3
  9. };
  10.     
  11. #define WORLDSIZE        16384
  12. #define START_PHASE        0
  13.  
  14. void drawButton(short button, Boolean hilite);
  15. Rect buttonRect(short button);
  16. void trackButton(Point where, short button, short hOffset, short vOffset);
  17. void drawMaze(Rect r, Rect world, Rect locationRect, short phase);
  18.  
  19.  
  20. Rect buttonRect(short button)
  21. {
  22.     Rect r = {0, 0, 32, 32};
  23.     Point location;
  24.     switch (button) {
  25.     case 0: case 4:
  26.         location.h = ICON_MARGIN;
  27.         location.v = (height(mazeWindow->portRect) - ICON_SIZE) / 2;
  28.         break;
  29.  
  30.     case 1: case 5:
  31.         location.h = (width(mazeWindow->portRect) - ICON_SIZE) / 2;
  32.         location.v = mazeWindow->portRect.bottom - ICON_SIZE - ICON_MARGIN;
  33.         break;
  34.  
  35.     case 2: case 6:
  36.         location.h = mazeWindow->portRect.right - ICON_SIZE - ICON_MARGIN;
  37.         location.v = (height(mazeWindow->portRect) - ICON_SIZE) / 2;
  38.         break;
  39.  
  40.     case 3: case 7:
  41.         location.h = (width(mazeWindow->portRect) - ICON_SIZE) / 2;
  42.         location.v = ICON_MARGIN;
  43.         break;
  44.     }
  45.     OffsetRect(&r, location.h, location.v);
  46.     return r;
  47. }
  48.  
  49.  
  50. void drawButton(short button, Boolean hilite)
  51. {
  52.     BitMap iconBits;
  53.     Handle icon = GetResource('ICON', button + (hilite ? ICON_HiLeft : ICON_Left));
  54.     Rect r = buttonRect(button);
  55.  
  56.     HLock(icon);
  57.     iconBits.baseAddr = *icon;
  58.     iconBits.rowBytes = 4;
  59.     iconBits.bounds.left   = 0;
  60.     iconBits.bounds.top    = 0;
  61.     iconBits.bounds.right  = 32;
  62.     iconBits.bounds.bottom = 32;
  63.  
  64.     CopyBits(&iconBits, &mazeWindow->portBits, &iconBits.bounds, &r, srcCopy, 0);
  65.     HUnlock(icon);
  66. }
  67.  
  68.  
  69. void drawMaze(Rect r, Rect world, Rect locationRect, short phase)
  70. {
  71.     Rect result;
  72.     if (SectRect(&locationRect, &world, &result)) {
  73.         short size = (short)(((unsigned long)world.right - (unsigned long)world.left) / 2);
  74.         if (size <= MAZE_LIMIT) {
  75.             OffsetRect(&world, r.left - locationRect.left, r.top - locationRect.top);
  76.             MoveTo(world.left + size, world.top + size);
  77.             switch (phase) {
  78.             case 0:
  79.                 LineTo(world.left + size, world.bottom);
  80.                 
  81.                 MoveTo(world.left, world.top + size);
  82.                 LineTo(world.left, world.top);
  83.                 LineTo(world.right, world.top);
  84.                 LineTo(world.right, world.top + size);
  85.                 break;
  86.                 
  87.             case 1:
  88.                 LineTo(world.left, world.top + size);
  89.     
  90.                 MoveTo(world.left + size, world.top);
  91.                 LineTo(world.right, world.top);
  92.                 LineTo(world.right, world.bottom);
  93.                 LineTo(world.left + size, world.bottom);
  94.                 break;
  95.                 
  96.             case 2:
  97.                 LineTo(world.left + size, world.top);
  98.                 
  99.                 MoveTo(world.left, world.top + size);
  100.                 LineTo(world.left, world.bottom);
  101.                 LineTo(world.right, world.bottom);
  102.                 LineTo(world.right, world.top + size);
  103.                 break;
  104.                 
  105.             case 3:
  106.                 LineTo(world.right, world.top + size);
  107.     
  108.                 MoveTo(world.left + size, world.top);
  109.                 LineTo(world.left, world.top);
  110.                 LineTo(world.left, world.bottom);
  111.                 LineTo(world.left + size, world.bottom);
  112.                 break;
  113.             }
  114.         } else {
  115.             unsigned char *pWall = walls + 4 * phase;
  116.             short quarter = size / 2;
  117.             Rect frame = world;
  118.             
  119.             OffsetRect(&frame, r.left - locationRect.left, r.top - locationRect.top);
  120.             switch (phase) {
  121.             case 0: case 2:
  122.                 MoveTo(frame.left, frame.top + quarter);
  123.                 LineTo(frame.left, frame.top + quarter + size);
  124.                 MoveTo(frame.right, frame.top + quarter);
  125.                 LineTo(frame.right, frame.top + quarter + size);
  126.                 break;
  127.                 
  128.             case 1: case 3:
  129.                 MoveTo(frame.left + quarter, frame.top);
  130.                 LineTo(frame.left + quarter + size, frame.top);
  131.                 MoveTo(frame.left + quarter, frame.bottom);
  132.                 LineTo(frame.left + quarter + size, frame.bottom);
  133.                 break;
  134.             }
  135.  
  136.  
  137.             world.right  -= size;
  138.             world.bottom -= size;
  139.             drawMaze(r, world, locationRect, *pWall++);
  140.             
  141.             OffsetRect(&world, 0, size);
  142.             drawMaze(r, world, locationRect, *pWall++);
  143.             
  144.             OffsetRect(&world, size, 0);
  145.             drawMaze(r, world, locationRect, *pWall++);
  146.             
  147.             OffsetRect(&world, 0, -size);
  148.             drawMaze(r, world, locationRect, *pWall++);
  149.         }
  150.     }
  151. }
  152.  
  153.  
  154. void doMazeDraw(void)
  155. {
  156.     Rect locationRect;
  157.     Rect world = {-WORLDSIZE, -WORLDSIZE, WORLDSIZE, WORLDSIZE};
  158.     Rect r = {-15, -15, 0, 0};
  159.     
  160.     OffsetRect(&r, mazeWindow->portRect.right, mazeWindow->portRect.bottom);
  161.     EraseRect(&mazeWindow->portRect);
  162.     GetClip(scratchRgn);
  163.     ClipRect(&r);
  164.     DrawGrowIcon(mazeWindow);
  165.     r = mazeWindow->portRect;
  166.     InsetRect(&r, ICON_SIZE + ICON_MARGIN * 2, ICON_SIZE + ICON_MARGIN * 2);
  167.     ClipRect(&r);
  168.     
  169.     locationRect = r;
  170.     OffsetRect(&locationRect, location.h - locationRect.left, location.v - locationRect.top);
  171.     InsetRect(&locationRect, -1, -1);
  172.     drawMaze(r, world, locationRect, START_PHASE);
  173.     SetClip(scratchRgn);
  174.     InsetRect(&r, -1, -1);
  175.     FrameRect(&r);
  176.     
  177.     drawButton(0, false);
  178.     drawButton(1, false);
  179.     drawButton(2, false);
  180.     drawButton(3, false);
  181. }
  182.  
  183.  
  184. void trackButton(Point where, short button, short hOffset, short vOffset)
  185. {
  186.     Rect locationRect;
  187.     Rect world = {-WORLDSIZE, -WORLDSIZE, WORLDSIZE, WORLDSIZE};
  188.     Rect r = buttonRect(button);
  189.     Rect inside = mazeWindow->portRect;
  190.     Boolean stillInside;
  191.     Boolean wasInside = false;
  192.     InsetRect(&inside, ICON_SIZE + ICON_MARGIN * 2, ICON_SIZE + ICON_MARGIN * 2);
  193.     GetClip(scratchRgn);
  194.     
  195.     do {
  196.         stillInside = PtInRect(where, &r);
  197.         if (stillInside != wasInside) {
  198.             wasInside = stillInside;
  199.             drawButton(button, stillInside);
  200.         }
  201.         if (stillInside) {
  202.             location.h -= hOffset;
  203.             location.v -= vOffset;
  204.             ScrollRect(&inside, hOffset, vOffset, scrollRgn);
  205.             SetClip(scrollRgn);
  206.             locationRect = H(scrollRgn).rgnBBox;
  207.             InsetRect(&locationRect, -1, -1);
  208.             OffsetRect(&locationRect, location.h - inside.left, location.v - inside.top);
  209.             drawMaze(H(scrollRgn).rgnBBox, world, locationRect, START_PHASE);
  210.             //PaintRect(&inside);
  211.             SetClip(scratchRgn);
  212.         }
  213.         GetMouse(&where);
  214.     } while (StillDown());
  215.     if (stillInside) {
  216.         drawButton(button, false);
  217.     }
  218. }
  219.  
  220.  
  221. void doMazeClick(Point where, short modifiers)
  222. {
  223.     Rect r;
  224.     
  225.     r = buttonRect(0);
  226.     if (PtInRect(where, &r)) {
  227.         trackButton(where, 0, SCROLL, 0);
  228.     } else {
  229.         r = buttonRect(1);
  230.         if (PtInRect(where, &r)) {
  231.             trackButton(where, 1, 0, -SCROLL);
  232.         } else {
  233.             r = buttonRect(2);
  234.             if (PtInRect(where, &r)) {
  235.                 trackButton(where, 2, -SCROLL, 0);
  236.             } else {
  237.                 r = buttonRect(3);
  238.                 if (PtInRect(where, &r)) {
  239.                     trackButton(where, 3, 0, SCROLL);
  240.                 }
  241.             }
  242.         }
  243.     }
  244. }